-
Notifications
You must be signed in to change notification settings - Fork 6.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce AD7124 ADC #84197
Introduce AD7124 ADC #84197
Conversation
9f6d73c
to
8c851ae
Compare
8c851ae
to
886f359
Compare
886f359
to
3b7e91f
Compare
Hi @MaureenHelm, could you review again? |
Hi @anangl , could you review the PR? |
Hi @anangl , this PR is waiting for your review. |
drivers/adc/adc_ad7124.c
Outdated
|
||
struct spi_buf tx_buf[] = {{ | ||
.buf = buffer_tx, | ||
.len = ((data->crc_enable == AD7124_ENABLE_CRC) ? len + 1 : len) + 1 + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the point in defining AD7124_*_CRC
symbols and comparing crc_enable
against them? It's a bool
, so why not just use (data->crc_enable ? len + 1 : len)
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
drivers/adc/adc_ad7124.c
Outdated
for (int i = 1; i < len + 2 + add_status_length; i++) { | ||
crc_buffer[i] = buffer_rx[i]; | ||
} | ||
crc_check = crc8(crc_buffer, len + 2 + add_status_length, | ||
AD7124_CRC8_POLYNOMIAL_REPRESENTATION, 0, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you really need to copy this buffer just to calculate CRC for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed unnecessary copy.
const struct spi_buf_set tx = {.buffers = tx_buf, .count = ARRAY_SIZE(tx_buf)}; | ||
const struct spi_buf_set rx = {.buffers = rx_buf, .count = ARRAY_SIZE(rx_buf)}; | ||
|
||
buffer_tx[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD | AD7124_COMM_REG_RA(reg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this first byte all that actually needs to be transmitted (and the rest will be ignored anyway)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
drivers/adc/adc_ad7124.c
Outdated
const struct spi_buf_set tx = {.buffers = tx_buf, .count = ARRAY_SIZE(tx_buf)}; | ||
const struct spi_buf_set rx = {.buffers = rx_buf, .count = ARRAY_SIZE(rx_buf)}; | ||
|
||
ret = spi_transceive_dt(spec, &tx, &rx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of the RX buffer set here, when this is a write register transaction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
drivers/adc/adc_ad7124.c
Outdated
|
||
struct ad7124_channel_config { | ||
struct ad7124_config_props props; | ||
uint32_t cfg_slot; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uint32_t
to store the slot index, when there are 8 slots?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed with uint8_t
drivers/adc/adc_ad7124.c
Outdated
int ret; | ||
|
||
data->dev = dev; | ||
data->spi_ready.spi_rdy_poll_cnt = AD7124_SPI_RDY_POLL_CNT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the point in storing this value in driver data if it is not modified afterwards?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoded added to the functions, removed from initialization
drivers/adc/adc_ad7124.c
Outdated
num_active_channels = POPCOUNT(data->channels); | ||
necessary = num_active_channels * sizeof(int32_t); | ||
|
||
if (sequence->options) { | ||
necessary *= (1 + sequence->options->extra_samplings); | ||
} | ||
|
||
if (sequence->buffer_size < necessary) { | ||
LOG_ERR("buffer size %u is too small, need %u", sequence->buffer_size, necessary); | ||
return -ENOMEM; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
data->channels
is the bitmask of configured channels and this code is supposed to check if the provided buffer is large enough for the sequence, which does not need to use all the configured channels. sequence->channels
should be used instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The AD7124 is using one channel to read all channels respectively so I was reading all the configured channels when reading command called. I changed the algorithm so currrently only the requested sequence->channels datas will be read like you said.
drivers/adc/adc_ad7124.c
Outdated
const struct spi_buf_set tx = {.buffers = tx_buf, .count = ARRAY_SIZE(tx_buf)}; | ||
const struct spi_buf_set rx = {.buffers = rx_buf, .count = ARRAY_SIZE(rx_buf)}; | ||
|
||
ret = spi_transceive_dt(spec, &tx, &rx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The RX buffer set does not seem to be needed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
3b7e91f
to
854c4b3
Compare
854c4b3
to
4cfce74
Compare
drivers/adc/adc_ad7124.c
Outdated
|
||
k_sem_take(&data->acquire_signal, K_FOREVER); | ||
|
||
uint16_t requested_channels = data->requested_channels; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use data->ctx.sequence.channels
instead of adding requested_channels
to struct adc_ad7124_data
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
drivers/adc/adc_ad7124.c
Outdated
static bool get_next_ch_idx(uint16_t ch_mask, uint16_t last_idx, uint16_t *new_idx) | ||
{ | ||
last_idx++; | ||
if (last_idx >= 16) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This 16 is AD7124_MAX_CHANNELS
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
if (ch_idx == adc_ch_id) { | ||
data->buffer++; | ||
} else { | ||
ch_idx = prev_ch_idx; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it needed to always read all the configured channels and then writing to the buffer only those selected for a given sequence, using this filtering? Wouldn't it make sense to only enable the channels required for the requested sequence when it is started?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried what you said. I disabled when the read command called and enabled only the selectes ones. However, via this method, Ad7124 is working inconsistently and stop at some point because AD7124 is resetting the all setup when some configurations changed. So when you enabled and disabled continously at every reading command, system stuck at some point. The second reason is that, Ad7124 have 16 channels so disabling and enabling is increasing the latency.
As a solution, I am just reading only the selected ones.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This link is exactly what I tried.
This commit introduces ad7124 adc driver. Signed-off-by: Yasin Ustuner <[email protected]>
This commit adds ad7124 binding. Signed-off-by: Yasin Ustuner <[email protected]>
This commit adds analog inputs for AD7124 ADC. Signed-off-by: Yasin Ustuner <[email protected]>
This commit adds build-only test of ad7124 spi based adc. Signed-off-by: Yasin Ustuner <[email protected]>
4cfce74
to
660d6ab
Compare
This PR introduces AD7124 Analog to Digital Converter:
See AD7124-4 for detailed information.
See AD7124-8 for detailed information.